/*
 *  Jiki - a small lightweight wiki engine.
 *
 *  Copyright 2008 Peter Halbmayer <phalbmayer@gmail.com
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 */


/**
 * JHTTP Server gives the Server core for this wiki implementation
 * although from the name it more belongs to the conn package but
 * the kind of protocol the server handles shall be exchangable in
 * the future and therefore servers should be placed in the core package
 */

package at.pmsa.jiki;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.util.Enumeration;
import java.util.Properties;

import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import at.pmsa.jiki.conn.Connection;
import at.pmsa.jiki.util.*;

public class JHTTPServer extends Service implements Runnable, IJConstants{
	protected static Properties props = new Properties();
	
	private static ServerSocket server;

	private static int port;

	/* the web server's virtual root */
	static File root;

	/* timeout on client connections */
	static int timeout = 0;

	/* max # worker threads */
	int workers = 5;
	
	static PrintStream log = null;

	static Activity activity;
	
    static DBMan dbMan;
    
    //contains the online wiki filesystem held in memory
    //necessary, because it seems that entries in android db needs to
    //be keyed by integer values, but for internal file handling
    //title of page seems easier
	
	public JHTTPServer(){
		try{
			JHTTPServer.port = 8000;
			server = new ServerSocket(port);
		}
		catch(IOException e){
			e.printStackTrace();
			System.exit(-1);
		}
	}
	
    protected void onCreate(){
    	Log.v("JHTTPServer", "Calling onCreate");
    	
//    	Properties prop = System.getProperties();
//    	Enumeration<?> propEnum = prop.propertyNames();
//    	while(propEnum.hasMoreElements()){
//    		String propName = (String)propEnum.nextElement();
//    		Log.v("JHTTPServer", propName + " = " + System.getProperty(propName));
//    	}
    	
    	Thread thr = new Thread(null, this, "JHTTPServer");
        thr.start();
    }
    
    protected void onStart(){
    	Log.v("JHTTPServer", "Calling onStart");
    }
    
    protected void onDestroy(){
    	Log.v("JHTTPServer", "Calling onDestroy");
    	dbMan.close();
    }

	@Override
    public IBinder onBind(Intent intent){
    	return null;
    }

//	@Override
	public IBinder getBinder() {
		// TODO Auto-generated method stub
		return null;
	}

	/* load jiki.properties from java.home */
	static void init(Activity a){
		activity = a;
		
		Log.v("JHTTPServer", "Starting init!");
		
		dbMan = new DBMan(activity);
		
		Log.v("JHTTPServer", "DBMan created!");
		
		if(!dbMan.fileExists("JHome"))
			dbMan.writeFile("JHome", HOMETEXT);
		
		Log.v("JHTTPServer", "JHome handled!");
		
		if(!dbMan.fileExists("JHelp"))
			dbMan.writeFile("JHelp", HELPTEXT);
		
		Log.v("JHTTPServer", "JHelp handled!");
	}
	
	public void run(){
		Log.v("", "Server listening on port " + port + "...");
	
		boolean alive = true;

		while(alive){
			try{
				Thread t = new Thread(new Connection(server.accept(), dbMan));
				t.start();
			}
			catch(IOException e){
				Log.e("JHTTPServer", "Server socket invalidated.\nRestarting...");
				try{
					server.close();
				}
				catch(IOException e1){
					// ignore - we are closing anyways.
				}
				try{
					server = new ServerSocket(port);
				}
				catch(IOException e1){
					Log.e("JHTTPServer", "Server suffered a severe error. Closing application...");
					alive = false;
				}
			}
		}
		Log.v("JHTTPServer", "Closing server gracefully...");
		try{
			server.close();
		}
		catch(IOException e){
			// ignore - we are closing anyways.
		}
	}
}
